package com.sun.redis.config.util;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.integration.redis.util.RedisLockRegistry;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;

/**
 * @description
 * @author 施瑞
 * @date 2022/2/24
 */
@Component
@Slf4j
public class DistributedRedisLockDemo {
    /**
     * redisLockRegistry
     */
    private RedisLockRegistry redisLockRegistry;

    /**
     * @param redisLockRegistry redis锁管理器
     *
     */
    @Autowired
    public DistributedRedisLockDemo(RedisLockRegistry redisLockRegistry) {
        this.redisLockRegistry = redisLockRegistry;
    }

    public void demo() throws Exception {
        try {
            String lockKey = "distributedRedisLockDemo";
            Lock lock = redisLockRegistry.obtain(lockKey);

            try {
                log.info("开始加锁");
                //尝试在指定时间内加锁，如果已经有其他锁锁住，获取当前线程不能加锁，则返回false，加锁失败；加锁成功则返回true
                boolean ifLock = lock.tryLock(3, TimeUnit.SECONDS);
                /*
                 * 可以获取到锁，说明当前没有线程在执行该方法
                 */
                if (ifLock) {
                    //执行业务
                } else {
                    log.info("线程[{}]未获取到锁，目前锁详情信息为：{}", Thread.currentThread().getName(), lock);
                }
            } catch (Exception e) {
                log.error("加锁出错:{}", e.getMessage());
                throw e;
            } finally {
                log.info("尝试解锁[{}]", lockKey);
                try {
                    lock.unlock();
                    log.info("[{}]解锁成功", lockKey);
                } catch (Exception e) {
                    log.error("解锁出错:{}", e.getMessage());
                }
            }
        } catch (Throwable e) {
            log.error("aop redis distributed lock error:{}", e.getLocalizedMessage());
            throw new Exception(e.getLocalizedMessage());
        }
    }
}
